using System;
using System.Collections;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.Humans;
using PHSRAG.Insight21.InsightWebControls;
using PHSRAG.Insight21.Policy;
using PHSRAG.Insight21.SearchContext;
using PHSRAG.Utility;
using Constants = PHSRAG.Insight21.InsightUtilities.Constants;
using Helper = PHSRAG.WebControls.Helper;

namespace PHSRAG.Insight21.Agreements
{
    /// <summary>
    /// The Contract Details page provides the information about the contract.  
    /// which includes subContract details for work subcontracted out, related protocols, 
    /// associated agreements, terms and conditions and Milestones. All of this information 
    /// are retrieved for a given agreement id.
    /// </summary>
    public partial class AgreementContractDetails : NoCachePage
    {
        #region Constants

        private const string AgreementsIdkey = "agreementIdKey_715A9505-97DF-4685-B3F6-A4B79CD16731";
        private const string AssociatedAgreementsExpandedKey = "AssociatedAgreementsExpanded_9572FCDE-47B6-4e7b-921E-D32AE6F02D45";
        private const string AwardedBudgetColumnName = "AwardedToDate";
        private const int BudgetColumnIndex = 2;
        private const string BudgetColumnName = "TotalBudget";
        private const string CollapseImageURL = "../Images/CollapseButtonOrange.gif";
        private const int DefaultAmount = 0;
        private const string ExcelReportControlFilePath = "../../Agreements/Reports/ContractDetailsExcel.ascx";
        private const string ExpandImageURL = "../Images/ExpandButtonOrange.gif";
        private const string FundNumberKey = "FundNumberKey_d6c4d45a-ec0b-4495-a9c7-ed7cb326798b";
        private const string MilestonesExpandedKey = "MilestonesExpanded__9572FCDE-47B6-4e7b-921E-D32AE6F02D45";
        private const int NameColumnIndex = 0;
        private const string PageCacheKey = "contractDetailsPage__9572FCDE-47B6-4e7b-921E-D32AE6F02D45";
        private const string RelatedProtocolsExpandedKey = "RelatedProtocolsExpanded_9572FCDE-47B6-4e7b-921E-D32AE6F02D45";
        private const string SubContractsExpandedKey = "SubContractsExpanded_9572FCDE-47B6-4e7b-921E-D32AE6F02D45";
        private const string TermsAndConditionsColumnName = "TermsAndConditions";
        private const string TermsAndConditionsExpandedKey = "TermsAndConditionsExpanded_9572FCDE-47B6-4e7b-921E-D32AE6F02D45";
        private const string TitleColumnName = "Title";

        #endregion

        #region Instance Variables (Private)

        private ICachePolicy cachePolicy;
        private Hashtable pageCache;
        private ICachePolicy pageCachePolicy;

        #endregion

        #region Private properties

        /// <summary>
        /// Gets the Contract Details object with its data loaded.
        /// This property gets the Contract Details object from the cache and checks if the object
        /// is null. If yes an instance of contract details is created and the object is loaded with
        /// data using the Agreement id and the domain user id of the logges in user. The contract object
        /// is then cached and returned.
        /// </summary>
        private ContractDetails ContractDetailsInstance
        {
            get
            {
                ContractDetails contractDetails = ResultsCache.GetObject(cachePolicy, ContractDetails.CacheKey) as ContractDetails;

                if (contractDetails == null)
                {
                    contractDetails = new ContractDetails();
                    UserContext userContext = cachePolicy.GetCachedObject(UserContext.CacheKey) as UserContext;
                    if (userContext == null)
                    {
                        throw new Exception("Failed to retrieve user context.");
                    }

                    contractDetails.Load(DataAccess.GetConnectionString(), userContext.DomainUserId, AgreementId, FundNumber);

                    ResultsCache.SetObject(cachePolicy, ContractDetails.CacheKey, contractDetails);
                }

                return contractDetails;
            }
        }

        /// <summary>
        /// Gets and sets the agreement id used for loading the contract details. 
        /// Returns an empty string if the value fetched from the pagecache policy is null.
        /// While setting the agreement Id, we check if it's different from the cached agreement Id.
        /// If yes, the stale object is uncached, and the new agreement Id is
        /// cached using the page cache policy.
        /// </summary>
        private int AgreementId
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.ContractDetailsPageKey) as Hashtable;
                return (h == null || h[AgreementsIdkey] == null) ? 0 : (int) h[AgreementsIdkey];
            }

            set
            {
                if (AgreementId != value)
                {
                    ResultsCache.PurgeObject(cachePolicy);

                    Hashtable h = pageCachePolicy.GetCachedObject(Keys.ContractDetailsPageKey) as Hashtable ?? new Hashtable();

                    h[AgreementsIdkey] = value;
                    pageCachePolicy.Cache(Keys.ContractDetailsPageKey, h);
                }
            }
        }

        /// <summary>
        /// Get and Set the fund number which is used to load the contract details data
        /// </summary>
        private string FundNumber
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.ContractDetailsPageKey) as Hashtable;
                return (h == null || h[FundNumberKey] == null) ? string.Empty : (string) h[FundNumberKey];
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.ContractDetailsPageKey) as Hashtable ?? new Hashtable();
                h[FundNumberKey] = value;
                pageCachePolicy.Cache(Keys.ContractDetailsPageKey, h);
            }
        }

        /// <summary>
        /// Gets/Sets whether the SubContracts part of the page is showing
        /// </summary>
        private bool SubContractsExpanded
        {
            get
            {
                object o = pageCache[SubContractsExpandedKey];
                return (o == null) ? (subContracts.Items.Count > 0) : (bool) o;
            }
            set
            {
                SetPanelExpandedState(SubContractsExpandedKey, subContractsPanel, subContractsPanelToggler, value);

                if (subContracts.Items.Count > 0)
                {
                    subContractsWarning.Text = value ? string.Empty : "Click button to show subcontracts";
                }
            }
        }

        /// <summary>
        /// Gets/Sets whether the Related Protocols part of the page is showing
        /// </summary>
        private bool RelatedProtocolsExpanded
        {
            get
            {
                object o = pageCache[RelatedProtocolsExpandedKey];
                return (o == null) ? (relatedProtocols.Items.Count > 0) : (bool) o;
            }
            set
            {
                SetPanelExpandedState(RelatedProtocolsExpandedKey, relatedProtocolsPanel, relatedProtocolsPanelToggler, value);

                if (relatedProtocols.Items.Count > 0)
                {
                    relatedProtocolsWarning.Text = value ? string.Empty : "Click button to show related protocols";
                }
            }
        }

        /// <summary>
        /// Gets/Sets whether the Associated Agreements part of the page is showing
        /// </summary>
        private bool AssociatedAgreementsExpanded
        {
            get
            {
                object o = pageCache[AssociatedAgreementsExpandedKey];
                return (o == null) ? (associatedAgreements.Items.Count > 0) : (bool) o;
            }
            set
            {
                SetPanelExpandedState(AssociatedAgreementsExpandedKey, associatedAgreementsPanel, associatedAgreementsPanelToggler, value);

                if (associatedAgreements.Items.Count > 0)
                {
                    associatedAgreementsWarning.Text = value ? string.Empty : "Click button to show associated agreements";
                }
            }
        }

        /// <summary>
        /// Gets/Sets whether the Terms & Conditions is showing
        /// </summary>
        //private bool TermsAndConditionsExpanded
        //{
        //    get
        //    {
        //        object o = pageCache[TermsAndConditionsExpandedKey];
        //        return (o == null) ? (termsAndConditions.Text != null) : (bool) o;
        //    }
        //    set
        //    {
        //        SetPanelExpandedState(TermsAndConditionsExpandedKey, termsAndConditionsPanel, termsAndConditionsPanelToggler, value);

        //        //if (termsAndConditions.Text.Length > 0)
        //        //{
        //        //    termsAndConditionsWarning.Text = value ? string.Empty : "Click button to show terms & conditions";
        //        //}
        //    }
        //}

        /// <summary>
        /// Gets/Sets whether the milestones part of the page is showing
        /// </summary>
        private bool MilestonesExpanded
        {
            get
            {
                object o = pageCache[MilestonesExpandedKey];
                return (o == null) ? (milestones.Items.Count > 0) : (bool) o;
            }
            set
            {
                SetPanelExpandedState(MilestonesExpandedKey, milestonesPanel, milestonesPanelToggler, value);

                if (milestones.Items.Count > 0)
                {
                    milestonesWarning.Text = value ? string.Empty : "Click button to show milestones";
                }
            }
        }

        /// <summary>
        /// Stores the setValue in the pageCache under the viewStateKey, sets the visibility on the panel to
        /// setValue, and sets the imageUrl of the toggler button based on setValue
        /// </summary>
        /// <param name="key">key to store the collapsed/expanded state of the panel in ViewState</param>
        /// <param name="panel">panel to set visibility on</param>
        /// <param name="toggler">button to display image for</param>
        /// <param name="setValue">value to set panel visibility and button image from</param>
        private void SetPanelExpandedState(string key, Panel panel, ImageButton toggler, bool setValue)
        {
            pageCache[key] = setValue;
            pageCachePolicy.Cache(PageCacheKey, pageCache);
            panel.Visible = setValue;
            toggler.ImageUrl = setValue ? CollapseImageURL : ExpandImageURL;
        }

        # endregion

        #region Event Handlers

        /// <summary>
        /// Purges the cache and sets the correct search context level before the breadcrumb performs a redirect.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnNavigate(object sender, CommandEventArgs e)
        {
            if (((CommandEventArgs) (e.CommandArgument)).CommandName == Convert.ToString((int) SearchCriteria.Level.Summary))
            {
                //set the search context's level to the correct level
                CommonSearchContext searchContext = (CommonSearchContext) cachePolicy.GetCachedObject(CommonSearchContext.CacheKey);
                searchContext.CurrentLevel = SearchCriteria.Level.Summary;
            }

            PurgeCache();
        }

        #region PageLoad

        /// <summary>
        /// Handler for the event raised when the page is being loaded. 
        /// When the page is loaded and is not a post back the following sequence of events happen:
        /// <list type="bullet">
        /// <item><description>breadCrumb is intialized</description></item>
        /// <item><description>Its checked if the incoming data for this page contains the relevant 
        /// data for loading this page, if not it raises an exception. </description></item>
        /// <item><description>Load the labels for the project header, if there is no fund number then don't display it</description></item>
        /// <item><description>Load the controls on the page with data</description></item>
        /// </list>
        /// </summary>
        /// <param name="sender">Control which raised the event</param>
        /// <param name="e">Arguments associated with the event</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            /*at098 - 02/01/2008*/
            reportDownload.SQLReportName = "Agmt_ContractDetails";

            annunciator.Message = string.Empty;
            annunciator.Title = string.Empty;
            string strInfoEdProposalNumber = "";

            pageCache = pageCachePolicy.GetCachedObject(PageCacheKey) as Hashtable ?? new Hashtable();

            if (!IsPostBack)
            {
                breadCrumb.Add(@"Contract Details", Settings.GetKeyValue(@"SubNavigation.
					AgreementDetails.ContractDetailsURL", string.Empty), Settings.GetKeyValue
                    (@"BreadCrumb.DetailPageLevel", AgreementConstants.DetailPageLevelValue));

                try
                {
                    Hashtable incomingHashTable = (Hashtable) cachePolicy.GetCachedObject(Constants.AgreementsConstants.AgreementDetailsKey);

                    if (incomingHashTable != null)
                    {
                        int agreementId = AgreementId = Convert.ToInt32(incomingHashTable[Keys.AgreementIdKey]);
                        string fundNumber = FundNumber = (string) incomingHashTable[Keys.FundNumberKey];
                        Agreement agreement = new Agreement(cachePolicy);
                        agreement.Load(DataAccess.GetConnectionString(), agreementId, fundNumber);
                        cachePolicy.Cache("currentAgreement", agreement);
                        //Proposal Number to use in the query string for InfoEd Integration.
                        strInfoEdProposalNumber = agreement.ProjectDetails.RexFolderNumber;
                        int budgetYear = (incomingHashTable[Keys.BudgetYearKey] == null) ? 0 : (int) incomingHashTable[Keys.BudgetYearKey];
                        projectHeaderBar.LoadProjectHeader(fundNumber, agreement.ResourceID, budgetYear);
                        incomingHashTable[Keys.RefreshBudgetDetailDataKey] = true;
                        pageCachePolicy.Cache(Constants.AgreementsConstants.AgreementDetailsKey, incomingHashTable);
                        LoadData();
                    }

                    agreementDetailsSubNavigation.SelectedLink = AgreementDetailsSubNavigation.ContractDetailCommand;
                }
                catch (Exception ex)
                {
                    annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
                }
            }

            if (Settings.GetKeyValue(UIUtility.IsInfoEdReadyForSSO, false))
            {
                string strInfoEdLandingPageURL = Settings.GetKeyValue(UIUtility.InfoEdTargetPageForAgreementContractDetails, "");
                strInfoEdLandingPageURL = string.Format(strInfoEdLandingPageURL, Settings.GetKeyValue(UIUtility.InfoEdLandingPageURLKey, ""), strInfoEdProposalNumber);
                aProductDocuments.HRef = strInfoEdLandingPageURL;
                aProductDocuments.InnerText = "Documents";
                //lbProjectDocuments.HRef = strInfoEdLandingPageURL;
                //lblTermsAndConditions.Text = "Project Documents";

            }
            else
            {
                //lbProjectDocuments.InnerText = "lbProjectDocuments";
                lblProjectDocuments.Text = "No terms and conditions found for this agreement";
                lblTermsAndConditions.Text = "Terms & Conditions";
            }

            SubContractsExpanded = SubContractsExpanded;
            RelatedProtocolsExpanded = RelatedProtocolsExpanded;
            AssociatedAgreementsExpanded = AssociatedAgreementsExpanded;
            //TermsAndConditionsExpanded = TermsAndConditionsExpanded;
            MilestonesExpanded = MilestonesExpanded;
        }

        #endregion

        # region DataGrid Events

        /// <summary>
        /// Handler for event raised when an item is data bound to SubContract grid.
        /// While binding data check if the amount field has negative values then assign a 
        /// style for displaying negative values. This formatting  is applied only to Item 
        /// types and alternating Item types.
        /// Budget amount is checked for null value or empty value, in both the cases amount
        /// is set as 0 if not the value is converted to decimal and checked for negative value.
        /// </summary>
        /// <param name="sender">Control which raised the event</param>
        /// <param name="e">Argument associated with the event</param>
        protected void OnSubContractItemDataBound(object sender, DataGridItemEventArgs e)
        {
            DataGridItem item = e.Item;

            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                object budgetAmount = ((DataRowView) item.DataItem)[BudgetColumnName];
                decimal amount = ((budgetAmount == null || budgetAmount.ToString() == string.Empty) 
                    ? DefaultAmount : Convert.ToDecimal(budgetAmount));

                if (amount < DefaultAmount)
                {
                    item.Cells[BudgetColumnIndex].CssClass = "DataGridNegativeCurrencyItem";
                }

                item.Cells[1].Text = Helper.ProcessDecimals(amount);

                object awardedBudgetAmount = ((DataRowView) item.DataItem)[AwardedBudgetColumnName];
                amount = ((awardedBudgetAmount == null || awardedBudgetAmount.ToString() == string.Empty) 
                    ? DefaultAmount : Convert.ToDecimal(awardedBudgetAmount));

                if (amount < DefaultAmount)
                {
                    item.Cells[2].CssClass = "DataGridNegativeCurrencyItem";
                }

                item.Cells[2].Text = Helper.ProcessDecimals(amount);
            }
        }

        protected void OnProtocolNumberCommand(object sender, CommandEventArgs e)
        {
            string protocolNumber = e.CommandArgument.ToString();
            UserContext userContext = (UserContext) cachePolicy.GetCachedObject(UserContext.CacheKey);

            DataTable protocolDetail = Protocol.GetProtocolDetailsForContract(DataAccess.ConnectionString, protocolNumber, userContext.DomainUserId);
            header.ModuleName = protocolDetail.Rows[0][1].ToString() == "H" ? "Humans" : "Animals";

            Hashtable outgoingData = new Hashtable();
            outgoingData.Add(Keys.ProtocolIdKey, protocolDetail.Rows[0][0]);
            outgoingData.Add(Keys.ProtocolAccessKey, protocolDetail.Rows[0][2].ToString());
            pageCachePolicy.Cache(Keys.ShowNewProcessBarKey, true);
            pageCachePolicy.Cache(Keys.IncomingDataKey, outgoingData);
            Response.Redirect("../Research/protocoldetails.aspx");
        }

        ///<summary> 
        /// Handler for event raised when an item is data bound to related protocols grid.
        /// While binding data check to the data grid the Title tool tip that gets displayed
        /// when a mouse over occurs on a cell in the Name column.
        /// </summary>
        /// <param name="sender">Control which raised the event</param>
        /// <param name="e">Argument associated with the event</param>
        protected void OnRelatedProtocolsItemDataBound(object sender, DataGridItemEventArgs e)
        {
            DataGridItem item = e.Item;
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                item.Cells[NameColumnIndex].ToolTip =
                    string.Format("Title: {0}", ((DataRowView) item.DataItem)[TitleColumnName].ToString().Trim());
            }
        }

        #endregion

        #region Downloads

        /// <summary>
        /// Invoked by the download bar when it catches an exception.
        /// </summary>
        /// <param name="sender">Control which raised the event</param>
        /// <param name="e">Argument associated with the event</param>
        private void OnDownloadFailed(object sender, CommandEventArgs e)
        {
            annunciator.Title = "Following error(s) occurred while downloading";
            annunciator.Message = ExceptionReport.GetExceptionInfo((Exception) e.CommandArgument, false);
        }

        /// <summary>
        /// Handles Send By Email button clicks by preparing a MailMessage to send back to the 
        /// InsightDownloadBar control
        /// </summary>
        /// <remarks>
        /// This method generates the raw information needed for the InsightDownloadBar to process 
        /// and send an e-mail with a link back to the page with the correct session settings.
        /// This page stores FundNumber  into the database.
        /// This page has no summary information, hence it passes an empty hashtable.
        /// </remarks>
        ///<param name="queryID">Last inserted value from the database</param>
        ///<param name="summaryInfo">Summary information to be send</param>
        ///<param name="webConfigURLKey">URL information to see the page</param>
        public void OnSendByEmail(out string webConfigURLKey, out int queryID, out Hashtable summaryInfo)
        {
            try
            {
                webConfigURLKey = "SubNavigation.AgreementDetails.ContractDetailsURL";
                string query = String.Format("{0}={1}", Keys.AgreementIdKey, AgreementId);
                queryID = ContractDetails.GetQueryId(query);
                summaryInfo = null;
            }
            catch (Exception ex)
            {
                webConfigURLKey = null;
                queryID = -1;
                summaryInfo = null;
                annunciator.Message = String.Format("{0} Error while sending by email.",
                    ExceptionReport.GetExceptionInfo(ex, false));
            }
        }

        #endregion

        #region Header

        /// <summary>
        /// Resets the subnavigation selected link(s) and purges the cache before the 
        /// header performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnHeaderNavigate(object sender, CommandEventArgs e)
        {
            PurgeCache();
            agreementsSubNavigation.Reset();
            agreementDetailsSubNavigation.Reset();
        }

        /// <summary>
        /// Purges the cache before the agreements subnavigation header performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnSubNavigate(object sender, CommandEventArgs e)
        {
            PurgeCache();
        }

        /// <summary>
        /// Purges the cache before the agreement details subnavigation header performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnDetailsSubNavigate(object sender, CommandEventArgs e)
        {
            PurgeCache();
        }

        #endregion

        #endregion

        # region Private Methods

        /// <summary>
        /// Loads the data in the datagrids displaying subcontract details, related protocols,
        /// associated agreements, milestones and in the multiline textbox displaying terms and
        /// conditions. This method checks if the tables retrieved have records subcontracts,
        /// related protocols, agreements, milestones and terms and condtions.
        /// Hides the toggler and displays a label informing the user that there is no data for that 
        /// section. 
        private void LoadData()
        {
            DataSet contractDetailsDataSet = ContractDetailsInstance.GetDataContainer();
            DataTable subContractsTable = contractDetailsDataSet.Tables[Constants.AgreementsConstants.SubContractsTableName];

            if (subContractsTable.Rows.Count == 0)
            {
                subContractsWarning.Text = "No subcontracts for this agreement";
                subContractsPanelToggler.Visible = false;
            }
            else
            {
                subContracts.DataSource = subContractsTable;
                subContracts.DataBind();
            }

            DataTable relatedProtocolsTable = contractDetailsDataSet.Tables[Constants.AgreementsConstants.RelatedProtocolsTableName];

            if (relatedProtocolsTable.Rows.Count == 0)
            {
                relatedProtocolsWarning.Text = "No related protocols for this agreement";
                relatedProtocolsPanelToggler.Visible = false;
            }
            else
            {
                relatedProtocols.DataSource = relatedProtocolsTable;
                relatedProtocols.DataBind();
            }

            DataTable associatedAgreementsTable = contractDetailsDataSet.Tables[Constants.AgreementsConstants.AssociatedAgreementsTableName];

            if (associatedAgreementsTable.Rows.Count == 0)
            {
                associatedAgreementsWarning.Text = "No associated agreements found for this agreement";
                associatedAgreementsPanelToggler.Visible = false;
            }
            else
            {
                associatedAgreements.DataSource = associatedAgreementsTable;
                associatedAgreements.DataBind();
            }

            //DataTable termsAndConditionsTable = contractDetailsDataSet.Tables[Constants.AgreementsConstants.TermsAndConditionsTableName];
            //string terms = string.Empty;

            //if (termsAndConditionsTable.Rows.Count > 0)
            //{
            //    terms = termsAndConditionsTable.Rows[0][TermsAndConditionsColumnName].ToString();
            //}

            //if (terms == string.Empty)
            //{
            //    termsAndConditionsWarning.Text = "No terms and conditions found for this agreement";
            //    termsAndConditionsPanelToggler.Visible = termsAndConditions.Visible = termsAndConditionsPanel.Visible = false;
            //    termsAndConditionsPanel.CssClass = "Invisible";
            //}
            //else
            //{
            //    termsAndConditions.Text = termsAndConditionsTable.Rows[0][TermsAndConditionsColumnName].ToString();
            //}

            DataTable milestonesTable = contractDetailsDataSet.Tables[Constants.AgreementsConstants.MileStonesTableName];

            if (milestonesTable.Rows.Count == 0)
            {
                milestonesWarning.Text = "No milestones found for this agreement";
                milestonesPanelToggler.Visible = false;
            }
            else
            {
                milestones.DataSource = milestonesTable;
                milestones.DataBind();
            }
        }

        /// <summary>
        /// Uncaches all objects with data for this page.
        /// </summary>
        private void PurgeCache()
        {
            ResultsCache.PurgeObject(cachePolicy);
        }

        #endregion

        #region GridToggle Event Handlers

        /// <summary>
        /// Toggles the visibilty of each section
        /// </summary>
        protected void OnSubContractsClick(object sender, ImageClickEventArgs e)
        {
            SubContractsExpanded = !SubContractsExpanded;
        }

        protected void OnRelatedProtocolsClick(object sender, ImageClickEventArgs e)
        {
            RelatedProtocolsExpanded = !RelatedProtocolsExpanded;
        }

        protected void OnAssociatedAgreementsClick(object sender, ImageClickEventArgs e)
        {
            AssociatedAgreementsExpanded = !AssociatedAgreementsExpanded;
        }

        //protected void OnTermsAndConditionsClick(object sender, ImageClickEventArgs e)
        //{
        //    TermsAndConditionsExpanded = !TermsAndConditionsExpanded;
        //}

        protected void OnMilestonesClick(object sender, ImageClickEventArgs e)
        {
            MilestonesExpanded = !MilestonesExpanded;
        }

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Handler for the event raised when the page is being initialized.
        /// Retrieve the cache policy in force.
        /// </summary>
        /// <param name="e">Arguments assocoiated with the event</param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
        }

        #endregion
    }
}